/*
 * 2021.03.27-Code rectification and function enhancement.
 *            Huawei Device Co., Ltd. <mobile@huawei.com>
 */

#include "../StdAfx.h"
#include "UIOption.h"

namespace DuiLib {
IMPLEMENT_DUICONTROL(COptionUI)
COptionUI::COptionUI()
    : m_bSelected(false),
      m_dwSelectedTextColor(0),
      m_dwSelectedBkColor(0),
      m_dwSelectedBkColor2(0),
      m_dwSelectedBkColor4(0)
{}

COptionUI::~COptionUI()
{
    if (!m_sGroupName.IsEmpty() && m_pManager)
        m_pManager->RemoveOptionGroup(m_sGroupName, this);
}

LPCTSTR COptionUI::GetClass() const
{
    return _T("OptionUI");
}

LPVOID COptionUI::GetInterface(LPCTSTR pstrName)
{
    if (_tcsicmp(pstrName, DUI_CTR_OPTION) == 0)
        return static_cast<COptionUI *>(this);
    return CButtonUI::GetInterface(pstrName);
}

void COptionUI::SetManager(CPaintManagerUI *pManager, CControlUI *pParent, bool bInit)
{
    CControlUI::SetManager(pManager, pParent, bInit);
    if (bInit && !m_sGroupName.IsEmpty()) {
        if (m_pManager)
            m_pManager->AddOptionGroup(m_sGroupName, this);
    }
}

LPCTSTR COptionUI::GetGroup() const
{
    return m_sGroupName;
}

void COptionUI::SetGroup(LPCTSTR pStrGroupName)
{
    if (pStrGroupName == nullptr) {
        if (m_sGroupName.IsEmpty())
            return;
        m_sGroupName.Empty();
    } else {
        if (m_sGroupName == pStrGroupName)
            return;
        if (!m_sGroupName.IsEmpty() && m_pManager)
            m_pManager->RemoveOptionGroup(m_sGroupName, this);
        m_sGroupName = pStrGroupName;
    }

    if (!m_sGroupName.IsEmpty()) {
        if (m_pManager)
            m_pManager->AddOptionGroup(m_sGroupName, this);
    } else {
        if (m_pManager)
            m_pManager->RemoveOptionGroup(m_sGroupName, this);
    }

    Selected(m_bSelected);
}

bool COptionUI::IsSelected() const
{
    return m_bSelected;
}

void COptionUI::Selected(bool bSelected, bool bforce)
{
    if (m_bSelected == bSelected && bforce == false) {
        return;
    }

    m_bSelected = bSelected;
    if (m_bSelected) {
        m_uButtonState |= UISTATE_SELECTED;
    } else {
        m_uButtonState &= ~UISTATE_SELECTED;
    }

    if (m_pManager != nullptr) {
        if (!m_sGroupName.IsEmpty()) {
            COptionUI *lastSelectedOption = nullptr;
            CStdPtrArray *aOptionGroup = m_pManager->GetOptionGroup(m_sGroupName);
            if (aOptionGroup == nullptr) {
                return;
            }
            for (int i = 0; i < aOptionGroup->GetSize(); i++) {
                COptionUI *pControl = static_cast<COptionUI *>(aOptionGroup->GetAt(i));
                if (pControl == nullptr) {
                    continue;
                }
                if (pControl == this) {
                    continue;
                }
                if (pControl->IsSelected()) {
                    lastSelectedOption = pControl;
                    break;
                }
            }

            if (m_bSelected) {
                CStdPtrArray *aOptionGroup = m_pManager->GetOptionGroup(m_sGroupName);
                if (aOptionGroup == nullptr) {
                    return;
                }
                for (int i = 0; i < aOptionGroup->GetSize(); i++) {
                    COptionUI *pControl = static_cast<COptionUI *>(aOptionGroup->GetAt(i));
                    if (pControl == nullptr) {
                        return;
                    }
                    if (pControl != this) {
                        pControl->Selected(false);
                    }
                }

                bool blocked = false;
                m_pManager->SendNotify(this, DUI_MSGTYPE_SELECTCHANGED, (WPARAM)&blocked);
                if (blocked) {
                    if (lastSelectedOption) {
                        lastSelectedOption->SetSelected(true);
                    }

                    SetSelected(false);
                }
            } else {
                m_pManager->SendNotify(this, DUI_MSGTYPE_SELECTCHANGED);
            }
        } else {
            m_pManager->SendNotify(this, DUI_MSGTYPE_SELECTCHANGED);
        }
    }

    Invalidate();
}

void COptionUI::SetSelected(bool bSelected)
{
    if (m_bSelected == bSelected) {
        return;
    }

    m_bSelected = bSelected;
    if (m_bSelected) {
        m_uButtonState |= UISTATE_SELECTED;
    } else {
        m_uButtonState &= ~UISTATE_SELECTED;
    }

    if (m_pManager != nullptr) {
        if (!m_sGroupName.IsEmpty()) {
            if (m_bSelected) {
                CStdPtrArray *aOptionGroup = m_pManager->GetOptionGroup(m_sGroupName);
                if (aOptionGroup == nullptr) {
                    return;
                }
                for (int i = 0; i < aOptionGroup->GetSize(); i++) {
                    COptionUI *pControl = static_cast<COptionUI *>(aOptionGroup->GetAt(i));
                    if (pControl == nullptr) {
                        continue;
                    }
                    if (pControl != this) {
                        pControl->Selected(false);
                    }
                }
            } else {
            }
        } else {
        }
    }

    Invalidate();
}

CDuiString COptionUI::GetToolTip() const
{
    CDuiString temp = CControlUI::GetToolTip();
    if (temp.IsEmpty() && (!m_bShowHtml)) {
        if ((m_uTextStyle & DT_END_ELLIPSIS) != 0) {
            temp = GetText();

            if ((m_uTextStyle & DT_END_ELLIPSIS) && (m_uTextStyle & DT_WORDBREAK) == False) {
                int width = m_rcItem.right - m_rcItem.left -
                    CResourceManager::GetInstance()->Scale(m_rcTextPadding.right) -
                    CResourceManager::GetInstance()->Scale(m_rcTextPadding.left);
                RECT rcText = { 0, 0, 9999, 9999 };
                int nLinks = 0;

                int targetFont =
                    (((m_uButtonState & UISTATE_SELECTED) != 0) && (selectedFont != -1)) ? selectedFont : m_iFont;

                CDuiString sText =
                    m_bEnabled ? GetText() : (GetDisableText().GetLength() ? GetDisableText() : GetText());
                if (m_bShowHtml) {
                    CRenderEngine::DrawHtmlText(m_pManager->GetPaintDC(), m_pManager, rcText, sText, m_iFont,
                        m_dwTextColor, nullptr, nullptr, nLinks, DT_CALCRECT | m_uTextStyle);
                } else {
                    CRenderEngine::DrawText(m_pManager->GetPaintDC(), m_pManager, rcText, sText, m_dwTextColor,
                        targetFont, DT_CALCRECT | m_uTextStyle);
                }

                int txtWidth = rcText.right - rcText.left;
                if (txtWidth < width) {
                    temp = _T("");
                }
            }
        }
    }

    return temp;
}

bool COptionUI::Activate()
{
    if (!CButtonUI::Activate()) {
        return false;
    }
    if (!m_sGroupName.IsEmpty()) {
        Selected(true);
    } else {
        Selected(!m_bSelected);
    }

    return true;
}

void COptionUI::SetEnabled(bool bEnable)
{
    CControlUI::SetEnabled(bEnable);
    if (!IsEnabled()) {
        if (m_bSelected) {
            m_uButtonState = UISTATE_SELECTED;
        } else {
            m_uButtonState = 0;
        }
    }
}

LPCTSTR COptionUI::GetSelectedImage()
{
    return m_sSelectedImage;
}

void COptionUI::SetSelectedImage(LPCTSTR pStrImage)
{
    m_sSelectedImage = pStrImage;
    Invalidate();
}

LPCTSTR COptionUI::GetSelectedHotImage()
{
    return m_sSelectedHotImage;
}

void COptionUI::SetSelectedHotImage(LPCTSTR pStrImage)
{
    m_sSelectedHotImage = pStrImage;
    Invalidate();
}

LPCTSTR COptionUI::GetSelectedPushedImage()
{
    return m_sSelectedPushedImage;
}

void COptionUI::SetSelectedPushedImage(LPCTSTR pStrImage)
{
    m_sSelectedPushedImage = pStrImage;
    Invalidate();
}

void COptionUI::SetSelectedTextColor(DWORD dwTextColor)
{
    m_dwSelectedTextColor = dwTextColor;
}

DWORD COptionUI::GetSelectedTextColor()
{
    if (m_pManager == nullptr) {
        return m_dwSelectedTextColor;
    }
    if (m_dwSelectedTextColor == 0) {
        m_dwSelectedTextColor = m_pManager->GetDefaultFontColor();
    }
    return m_dwSelectedTextColor;
}

void COptionUI::SetSelectedBkColor(DWORD dwBkColor)
{
    m_dwSelectedBkColor = dwBkColor;
}

DWORD COptionUI::GetSelectBkColor()
{
    return m_dwSelectedBkColor;
}

void COptionUI::SetSelectedBkColor2(DWORD dwBkColor)
{
    m_dwSelectedBkColor2 = dwBkColor;
}

DWORD COptionUI::GetSelectBkColor2()
{
    return m_dwSelectedBkColor2;
}

void COptionUI::SetSelectedBkColor4(DWORD dwBkColor)
{
    m_dwSelectedBkColor4 = dwBkColor;
}

DWORD COptionUI::GetSelectBkColor4()
{
    return m_dwSelectedBkColor4;
}

LPCTSTR COptionUI::GetSelectedForedImage()
{
    return m_sSelectedForeImage;
}

void COptionUI::SetSelectedForedImage(LPCTSTR pStrImage)
{
    m_sSelectedForeImage = pStrImage;
    Invalidate();
}

void COptionUI::SetSelectedDisabledImage(LPCTSTR pStrImage)
{
    selectedDisabledImage = pStrImage;
    Invalidate();
}

void COptionUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
{
    const int radix = 16;
    if (pstrValue == nullptr) {
        return;
    }
    if (_tcsicmp(pstrName, _T("group")) == 0) {
        SetGroup(pstrValue);
    } else if (_tcsicmp(pstrName, _T("selected")) == 0) {
        Selected(_tcsicmp(pstrValue, _T("true")) == 0);
    } else if (_tcsicmp(pstrName, _T("selectedimage")) == 0) {
        SetSelectedImage(pstrValue);
    } else if (_tcsicmp(pstrName, _T("selectedhotimage")) == 0) {
        SetSelectedHotImage(pstrValue);
    } else if (_tcsicmp(pstrName, _T("selectedpushedimage")) == 0) {
        SetSelectedPushedImage(pstrValue);
    } else if (_tcsicmp(pstrName, _T("selectedforeimage")) == 0) {
        SetSelectedForedImage(pstrValue);
    } else if (_tcsicmp(pstrName, _T("selecteddisabledimage")) == 0) {
        SetSelectedDisabledImage(pstrValue);
    } else if (_tcsicmp(pstrName, _T("selectedbkcolor")) == 0) {
        if (*pstrValue == _T('#')) {
            pstrValue = ::CharNext(pstrValue);
        }
        LPTSTR pstr = nullptr;
        DWORD clrColor = _tcstoul(pstrValue, &pstr, radix);
        SetSelectedBkColor(clrColor);
    } else if (_tcsicmp(pstrName, _T("selectedbkcolor2")) == 0) {
        if (*pstrValue == _T('#')) {
            pstrValue = ::CharNext(pstrValue);
        }
        LPTSTR pstr = nullptr;
        DWORD clrColor = _tcstoul(pstrValue, &pstr, radix);
        SetSelectedBkColor2(clrColor);
    } else if (_tcsicmp(pstrName, _T("selectedbkcolor4")) == 0) {
        if (*pstrValue == _T('#')) {
            pstrValue = ::CharNext(pstrValue);
        }
        LPTSTR pstr = nullptr;
        DWORD clrColor = _tcstoul(pstrValue, &pstr, radix);
        SetSelectedBkColor4(clrColor);
    } else if (_tcsicmp(pstrName, _T("selectedtextcolor")) == 0) {
        if (*pstrValue == _T('#')) {
            pstrValue = ::CharNext(pstrValue);
        }
        LPTSTR pstr = nullptr;
        DWORD clrColor = _tcstoul(pstrValue, &pstr, radix);
        SetSelectedTextColor(clrColor);
    } else if (_tcsicmp(pstrName, _T("selectedfont")) == 0) {
        selectedFont = _ttoi(pstrValue);
    } else {
        CButtonUI::SetAttribute(pstrName, pstrValue);
    }
}

void COptionUI::PaintBkColor(HDC hDC)
{
    const int nSteps = 16;
    if (IsSelected()) {
        if (m_dwSelectedBkColor != 0) {
            if (m_dwSelectedBkColor2 != 0) {
                CRenderEngine::DrawGradient(hDC, m_rcPaint, GetAdjustColor(m_dwSelectedBkColor),
                    GetAdjustColor(m_dwSelectedBkColor2), true, nSteps);
            } else if (m_dwSelectedBkColor4 != 0) {
                CRenderEngine::DrawGradient(hDC, m_rcPaint, GetAdjustColor(m_dwSelectedBkColor),
                    GetAdjustColor(m_dwSelectedBkColor4), false, nSteps);
            } else {
                CRenderEngine::DrawColor(hDC, m_rcPaint, GetAdjustColor(m_dwSelectedBkColor), m_bkRound);
            }
        }
    } else {
        return CButtonUI::PaintBkColor(hDC);
    }
}

void COptionUI::PaintStatusImage(HDC hDC)
{
    if (IsSelected() && IsEnabled()) {
        if ((m_uButtonState & UISTATE_PUSHED) != 0 && !m_sSelectedPushedImage.IsEmpty()) {
            if (!DrawImage(hDC, (LPCTSTR)m_sSelectedPushedImage)) {
            } else {
                return;
            }
        } else if ((m_uButtonState & UISTATE_HOT) != 0 && !m_sSelectedHotImage.IsEmpty()) {
            if (!DrawImage(hDC, (LPCTSTR)m_sSelectedHotImage)) {
            } else {
                return;
            }
        }

        if (!m_sSelectedImage.IsEmpty()) {
            if (!DrawImage(hDC, (LPCTSTR)m_sSelectedImage)) {
            }
        }
    } else {
        if (IsSelected() && !IsEnabled() && !selectedDisabledImage.IsEmpty()) {
            DrawImage(hDC, (LPCTSTR)selectedDisabledImage);
        } else {
            CButtonUI::PaintStatusImage(hDC);
        }
    }
}

void COptionUI::PaintForeImage(HDC hDC)
{
    if (IsSelected() && IsEnabled()) {
        if (!m_sSelectedForeImage.IsEmpty()) {
            if (!DrawImage(hDC, (LPCTSTR)m_sSelectedForeImage)) {
            } else {
                return;
            }
        }
    }

    return CButtonUI::PaintForeImage(hDC);
}

void COptionUI::PaintText(HDC hDC)
{
    if (m_pManager == nullptr) {
        return;
    }
    if ((m_uButtonState & UISTATE_SELECTED) != 0) {
        DWORD oldTextColor = m_dwTextColor;
        if (m_dwSelectedTextColor != 0) {
            m_dwTextColor = m_dwSelectedTextColor;
        }

        if (m_dwTextColor == 0) {
            m_dwTextColor = m_pManager->GetDefaultFontColor();
        }
        if (m_dwDisabledTextColor == 0) {
            m_dwDisabledTextColor = m_pManager->GetDefaultDisabledColor();
        }

        CDuiString sText = GetText();
        if (sText.IsEmpty()) {
            return;
        }
        int nLinks = 0;
        RECT m_rcTextPadding = CButtonUI::m_rcTextPadding;
        CResourceManager::GetInstance()->Scale(&m_rcTextPadding);
        RECT rc = m_rcItem;
        rc.left += m_rcTextPadding.left;
        rc.right -= m_rcTextPadding.right;
        rc.top += m_rcTextPadding.top;
        rc.bottom -= m_rcTextPadding.bottom;

        UINT m_uTextStyle = CButtonUI::m_uTextStyle;
        if (m_bAutoCalcHeight && m_cxyFixed.cx) {
            m_uTextStyle &= ~(DT_SINGLELINE);
            m_uTextStyle = m_uTextStyle | DT_WORDBREAK;
        }

        if (m_bShowHtml) {
            CRenderEngine::DrawHtmlText(hDC, m_pManager, rc, sText, IsEnabled() ? m_dwTextColor : m_dwDisabledTextColor,
                selectedFont != -1 ? selectedFont : m_iFont, nullptr, nullptr, nLinks, m_uTextStyle);
        } else {
            CRenderEngine::DrawText(hDC, m_pManager, rc, sText, IsEnabled() ? m_dwTextColor : m_dwDisabledTextColor,
                selectedFont != -1 ? selectedFont : m_iFont, m_uTextStyle);
        }

        m_dwTextColor = oldTextColor;
    } else {
        CButtonUI::PaintText(hDC);
    }

#ifdef TEST_TIPS_BUILD
    ShowToolTips();
#endif
}

IMPLEMENT_DUICONTROL(CCheckBoxUI)

LPCTSTR CCheckBoxUI::GetClass() const
{
    return _T("CheckBoxUI");
}
LPVOID CCheckBoxUI::GetInterface(LPCTSTR pstrName)
{
    if (_tcsicmp(pstrName, DUI_CTR_CHECKBOX) == 0) {
        return static_cast<CCheckBoxUI *>(this);
    }
    return COptionUI::GetInterface(pstrName);
}

void CCheckBoxUI::SetCheck(bool bCheck)
{
    Selected(bCheck);
}

bool CCheckBoxUI::GetCheck() const
{
    return IsSelected();
}

CCheckBoxUI::CCheckBoxUI() : m_bAutoCheck(FALSE) {}

CCheckBoxUI::~CCheckBoxUI() {}

void CCheckBoxUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
{
    if (_tcsicmp(pstrName, _T("EnableAutoCheck")) == 0) {
        SetAutoCheck(_tcsicmp(pstrValue, _T("true")) == 0);
    }

    COptionUI::SetAttribute(pstrName, pstrValue);
}
void CCheckBoxUI::SetAutoCheck(bool bEnable)
{
    m_bAutoCheck = bEnable;
}
void CCheckBoxUI::DoEvent(TEventUI &event)
{
    if (!IsMouseEnabled() && event.Type > UIEVENT__MOUSEBEGIN && event.Type < UIEVENT__MOUSEEND) {
        if (m_pParent != nullptr) {
            m_pParent->DoEvent(event);
        } else {
            COptionUI::DoEvent(event);
        }
        return;
    }
    if (m_pManager == nullptr) {
        return;
    }
    if (m_bAutoCheck && (event.Type == UIEVENT_BUTTONDOWN || event.Type == UIEVENT_DBLCLICK)) {
        if (::PtInRect(&m_rcItem, event.ptMouse) && IsEnabled()) {
            SetCheck(!GetCheck());
            m_pManager->SendNotify(this, DUI_MSGTYPE_CHECKCLICK, 0, 0);
            Invalidate();
        }
        return;
    }
    COptionUI::DoEvent(event);
}
void CCheckBoxUI::Selected(bool bSelected)
{
    if (m_bSelected == bSelected) {
        return;
    }
    m_bSelected = bSelected;
    if (m_bSelected) {
        m_uButtonState |= UISTATE_SELECTED;
    } else {
        m_uButtonState &= ~UISTATE_SELECTED;
    }

    if (m_pManager != nullptr) {
        if (!m_sGroupName.IsEmpty()) {
            if (m_bSelected) {
                CStdPtrArray *aOptionGroup = m_pManager->GetOptionGroup(m_sGroupName);
                if (aOptionGroup == nullptr) {
                    return;
                }
                for (int i = 0; i < aOptionGroup->GetSize(); i++) {
                    COptionUI *pControl = static_cast<COptionUI *>(aOptionGroup->GetAt(i));
                    if (pControl == nullptr) {
                        return;
                    }
                    if (pControl != this) {
                        pControl->Selected(FALSE);
                    }
                }
                m_pManager->SendNotify(this, DUI_MSGTYPE_SELECTCHANGED, m_bSelected, 0);
            }
        } else {
            m_pManager->SendNotify(this, DUI_MSGTYPE_SELECTCHANGED, m_bSelected, 0);
        }
    }

    Invalidate();
}
}